#include "dbqueriesthread.h"

#include <QDebug>
#include <QThread>
#include <QTimerEvent>
#include "framework.h"
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>

CNS_INIT(DbQueryBaseThread)
CNS_REGISTER_CNS_COM_FACTORY2(DbQueryBaseThread, CnsComponent)
CNS_INIT_END


CNS_INIT(DbQueriesThread)
CNS_REGISTER_CNS_COM_FACTORY2(DbQueriesThread, CnsComponent)
CNS_INIT_END

SysDbQueriesThread::SysDbQueriesThread()
{

}

void SysDbQueriesThread::f_initDbQueriesThread(CnsComponentPtr com, QVariantHash& props, QScopedPointer<QThread>& thread)
{
    DbQueriesThread* threadCom = static_cast<DbQueriesThread*>(com.data());
    threadCom->setProps(std::move(props));
    com->moveToThread(thread.data());
    connect(thread.data(), &QThread::started, com.data(), [this,com,threadCom]()
    {
        QString dbID;
        com->exec("query", Q_ARG(QString &, dbID), QStringList(), Q_ARG(QVariantHash&, threadCom->getProps()));
        QSqlDatabase::removeDatabase(dbID);

        stop(com);
    }, Qt::AutoConnection);

//    connect(thread.data(), &QThread::finished, com.data(), [this,com]()
//    {
//    }, Qt::AutoConnection);
    thread->start();
}

DbQueriesThread::DbQueriesThread()
{
}

DbQueriesThread::~DbQueriesThread()
{
}

bool SysDbQueriesThread::query_b(CnsComponentPtr com, QString &dbID, QVariantHash &props)
{
    static ulong unique = 0;
    const QString& dbUser = com->property("dbUser").toString();
    const QString& dbName = com->property("dbName").toString();
    int port = com->property("port").toInt();
    const QString& passwd = com->property("passwd").toString();
    const QString& hostName = com->property("hostName").toString();
    const QString& dbType = com->property("dbType").toString();

    const QStringList &l = props["readSqlsAndSplit"].toStringList();
    if(l.size())
    {
        dbID = "DbQueriesThread"+QString::number(unique++);
        QSqlError err;
        QSqlDatabase db = QSqlDatabase::addDatabase(dbType, dbID);

        db.setPort(port);

        db.setHostName(hostName);
        db.setUserName(dbUser);
        db.setPassword(passwd);
        db.setDatabaseName(dbName);
        if (db.open()) {
            QSqlQuery q(db);

            for(QStringList::const_iterator it = l.begin(); it != l.end(); it ++)
            {
            //        qDebug() << props.value(DBQUERY_PARAM_SQL).toString().replace('\n', ' ');
                if(!q.exec(*it))
                {
                    err = db.lastError();
                    qDebug() << "text="<<err.text() << "driverText=" \
                             << err.driverText() << "databaseText=" << err.databaseText();
                    props.insert("status", tr("query error"));
                    db.close();
                    return false;
                }
            }
        } else{
            QSqlQuery q;
            err = db.lastError();
            QString result;
            QTextStream(&result) <<"text="<<err.text() << "driverText=" \
                                  << err.driverText() << "databaseText=" << err.databaseText();
            CNSLOG_DEBUG(result);

            props.insert("status", tr("open error"));

        }

        db.close();
    }
    return true;
}

void SysDbQueriesThread::stop(CnsComponentPtr com)
{
    DbQueriesThread* thread = static_cast<DbQueriesThread*>(com.data());
    thread->getWorkThread()->quit();
    thread->setDead(true);
    if(thread->isForceStop()){
        return;
    }
    emit thread->dbQueryThreadFinished(com);
}

